//
// Created by mio on 25-5-9.
//

#ifndef DEFINE_H
#define DEFINE_H

#include <cstdint>
#include <array>
#include <string>
#include <sys/sysinfo.h>

#pragma pack(push,1)
enum Cmd : uint16_t
{
    MONITOR,
    ERROR,
    LOGIN,
    REGISTER,
    DESTORY
};

enum ResultCode
{
    S_OK = 0,
    SERVER_ERROR,
    REQUEST_TIMEOUT,
    ALREADY_REDISTERED,
    USER_DISAPPER,
    ALREADY_LOGIN,
    VERFICATE_FAILED
};

struct packet_head {
    packet_head() :len(-1), cmd(-1) { }
    uint16_t len;
    uint16_t cmd;
};

struct UserLogin : public packet_head
{
    UserLogin() : packet_head()
    {
        cmd = LOGIN;
        len = sizeof(UserLogin);
        code.fill('\0');
        count.fill('\0');
        passwd.fill('\0');
    }

    void SetCode(const std::string str) { str.copy(code.data(), code.size(), 0); }
    std::string GetCode() { return std::string(code.data()); }

    void SetCount(const std::string& str) { str.copy(count.data(), count.size(), 0); }
    std::string GetCount() { return std::string(count.data()); }

    void SetPasswd(const std::string str) { str.copy(passwd.data(), passwd.size(), 0); }
    std::string GetPasswd() { return std::string(passwd.data()); }

    std::array<char, 20> code;
    std::array<char, 12> count;
    std::array<char, 33> passwd; // MD5
    uint64_t timestamp;
};

struct LoginResult : public packet_head
{
    LoginResult() : packet_head()
    {
        cmd = LOGIN;
        len = sizeof(LoginResult);
        port = 0;
        SvrIP.fill('\0');
    }

    void SetIP(const std::string& str) { str.copy(SvrIP.data(), SvrIP.size(), 0); }
    std::string GetIP() { return std::string(SvrIP.data()); }

    ResultCode result;
    uint16_t port;
    std::array<char, 16> SvrIP;
};

struct UserRegister: public packet_head
{
    UserRegister() : packet_head()
    {
        cmd = REGISTER;
        len = sizeof(UserRegister);

        code.fill('\0');
        name.fill('\0');
        count.fill('\0');
        passwd.fill('\0');
    }

    void SetCode(const std::string str) { str.copy(code.data(), code.size(), 0); }
    std::string GetCode() { return std::string(code.data()); }

    void SetName(const std::string str) { str.copy(name.data(), name.size(), 0); }
    std::string GetName() { return std::string(name.data()); }

    void SetCount(const std::string& str) { str.copy(count.data(), count.size(), 0); }
    std::string GetCount() { return std::string(count.data()); }

    void SetPasswd(const std::string str) { str.copy(passwd.data(), passwd.size(), 0); }
    std::string GetPasswd() { return std::string(passwd.data()); }

    std::array<char, 20> code;
    std::array<char, 20> name;
    std::array<char, 12> count;
    std::array<char, 20> passwd; // MD5
    uint64_t timestamp;
};

struct RegisterResult : public packet_head
{
    RegisterResult() : packet_head()
    {
        cmd = REGISTER;
        len = sizeof(RegisterResult);
    }

    ResultCode result;
};

/* 用户注销 */
struct UserDestory: public packet_head
{
    UserDestory() : packet_head()
    {
        cmd = DESTORY;
        len = sizeof(UserDestory);

        code.fill('\0');
    }

    void SetCode(const std::string str) { str.copy(code.data(), code.size(), 0); }
    std::string GetCode() { return std::string(code.data()); }

    std::array<char, 20> code;
};

struct Monitor_body : public packet_head {
    Monitor_body()
        :packet_head()
    {
        cmd = MONITOR;
        len = sizeof(Monitor_body);
        ip.fill('\0');
    }
    void SetIp(const std::string& str)
    {
        str.copy(ip.data(), ip.size(), 0);
    }
    std::string GetIp()
    {
        return std::string(ip.data());
    }
    uint8_t mem;
    std::array<char, 16> ip;
    uint16_t port;
};

#pragma pack(pop)

#endif //DEFINE_H